package com.maocwer.framework.orm;
import java.io.Serializable;
import java.util.Collections;
import java.util.List;

import org.apache.commons.lang.StringUtils;
 



/**

 * 与具体ORM实现无关的分页参数及查询结果封装.

 * 注意所有序号从1开始.

 * 

 * @param <T> Page中记录的类型.

 * 

 */

public abstract class Page<T> implements Serializable {
	private static final long serialVersionUID = -2612043141050375762L;

	// 公共变量 //

	public static final String ASC = "asc";

	public static final String DESC = "desc";

	// 分页参数 //

	protected int number = 1;

	protected int size = 10;

	protected int range = 5;

	protected String orderBy = null;

	protected String order = null;

	protected boolean autoCount = true;

	// 返回结果 //

	protected List<T> result = Collections.emptyList();

	protected long totalCount = -1;
	// 应用程序的根路径
	protected String contextPath =  null;
	/**
	 * 得到应用程序的根路径
	 * 
	 * @return String 应用程序的根路径
	 */
	public String getContextPath() {
		return contextPath;
	}

	public void setContextPath(String contextPath) {
		this.contextPath = contextPath;
	}

	/**
	 * 构造函数


	 */
	public Page() {

		super();

	}

	/**
	 * 构造函数


	 * 
	 * @param pageSize
	 *            每页显示记录条数
	 */
	public Page(final int pageSize) {

		setSize(pageSize);

	}

	/**
	 * 构造函数


	 * 
	 * @param pageSize
	 *            每页显示记录条数
	 * @param autoCount
	 *            查询对象时是否自动另外执行count查询获取总记录数
	 */
	public Page(final int pageSize, final boolean autoCount) {

		setSize(pageSize);

		this.autoCount = autoCount;

	}

	// 查询参数访问函数 //

	/**
	 * 
	 * 获得当前页的页号,序号从1开始,默认为1.
	 * 
	 * @return int 当前页的页号
	 */

	public int getNumber() {

		return number;

	}

	/**
	 * 
	 * 设置当前页的页号,序号从1开始,低于1时自动调整为1.
	 * 
	 * @param number
	 *            当前页的页号
	 */

	public void setNumber(final int number) {

		this.number = number;

		if (number < 1) {

			this.number = 1;

		}

	}

	/**
	 * 
	 * 获得每页的记录数量,默认为1.
	 * 
	 * @return int 每页的记录数量


	 */

	public int getSize() {

		return size;

	}

	/**
	 * 
	 * 设置每页的记录数量,低于1时自动调整为1.
	 * 
	 * @param size
	 *            每页的记录数量


	 */

	public void setSize(final int size) {

		this.size = size;

		if (size < 1) {

			this.size = 1;

		}

	}

	/**
	 * 
	 * 根据pageNo和pageSize计算当前页第一条记录在总结果集中的位置,序号从1开始.
	 * 
	 * @return int 首页记录在总记录中的开始位置


	 */

	public int getFirst() {

		return ((number - 1) * size) + 1;

	}

	/**
	 * 
	 * 获得排序字段,无默认值.多个排序字段时用','分隔.
	 * 
	 * @return String 排序字段
	 */

	public String getOrderBy() {

		return orderBy;

	}

	/**
	 * 设置排序字段,多个排序字段时用','分隔.
	 * 
	 * @param orderBy
	 *            需要排序的字段
	 */

	public void setOrderBy(final String orderBy) {

		this.orderBy = orderBy;

	}

	/**
	 * 
	 * 是否已设置排序字段,无默认值.
	 */

	public boolean isOrderBySetted() {

		return StringUtils.isNotBlank(orderBy);

	}

	/**
	 * 
	 * 获得排序方向.
	 * 
	 * 
	 * 
	 * @param order
	 *            可选值为desc或asc,多个排序字段时用','分隔.
	 */

	public String getOrder() {

		return order;

	}

	/**
	 * 
	 * 设置排序方式向.
	 * 
	 * @param order
	 *            可选值为desc或asc,多个排序字段时用','分隔.
	 */

	public void setOrder(final String order) {

		// 检查order字符串的合法值



		String[] orders = StringUtils.split(StringUtils.lowerCase(order), ',');

		for (String orderStr : orders) {

			if (!StringUtils.equals(DESC, orderStr)
					&& !StringUtils.equals(ASC, orderStr))

				throw new IllegalArgumentException("排序方向" + orderStr + "不是合法值");

		}

		this.order = StringUtils.lowerCase(order);

	}

	/**
	 * 
	 * 查询对象时是否自动另外执行count查询获取总记录数, 默认为false.
	 * 
	 * @return boolean
	 */

	public boolean isAutoCount() {

		return autoCount;

	}

	/**
	 * 
	 * 查询对象时是否自动另外执行count查询获取总记录数.
	 * 
	 * @param autoCount
	 */

	public void setAutoCount(final boolean autoCount) {

		this.autoCount = autoCount;

	}

	/**
	 * 
	 * 取得页内的记录列表.
	 * 
	 * @return list
	 */

	public List<T> getResult() {

		return result;

	}

	/**
	 * 设置页内的记录列表


	 * 
	 * @param result
	 */
	public void setResult(final List<T> result) {

		this.result = result;

	}

	/**
	 * 
	 * 取得总记录数, 默认值为-1.
	 * 
	 * @return long
	 */

	public long getTotalCount() {

		return totalCount;

	}

	/**
	 *设置总记录数
	 * 
	 * @param totalCount
	 */
	public void setTotalCount(final long totalCount) {

		this.totalCount = totalCount;

	}

	/**
	 * 
	 * 根据pageSize与totalCount计算总页数, 默认值为-1.
	 * 
	 * @return long
	 */

	public long getTotalPages() {

		if (totalCount < 0)

			return -1;

		long count = totalCount / size;

		if (totalCount % size > 0) {

			count++;

		}

		return count;

	}

	/**
	 * 
	 * 是否还有下一页.
	 * 
	 * @return boolean
	 */

	public boolean isHasNext() {

		return (number + 1 <= getTotalPages());

	}

	/**
	 * 
	 * 取得下页的页号, 序号从1开始. 当前页为尾页时仍返回尾页序号.
	 * 
	 * @return int
	 */

	public int getNextPage() {

		if (isHasNext())

			return number + 1;

		else

			return number;

	}

	/**
	 * 
	 * 是否还有上一页.
	 * 
	 * @return boolean
	 */

	public boolean isHasPre() {

		return (number - 1 >= 1);

	}

	/**
	 * 
	 * 取得上页的页号, 序号从1开始.
	 * 
	 * 当前页为首页时返回首页序号.
	 * 
	 * @return int
	 */

	public int getPrePage() {

		if (isHasPre())

			return number - 1;

		else

			return number;

	}
	/**
	 * 
	 * 分页展示
	 * 
	 * @return String 在页面上显示的分页栏
	 */

	public abstract String getPager() ;
}

